#!/bin/bash

# 认证服务强制清理脚本
# 用于清理所有认证服务进程和相关资源

set -e

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
BLUE='\033[0;34m'
NC='\033[0m'

# 日志函数
log_info() {
    echo -e "${GREEN}[INFO]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_warn() {
    echo -e "${YELLOW}[WARN]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

log_error() {
    echo -e "${RED}[ERROR]${NC} $(date '+%Y-%m-%d %H:%M:%S') $1"
}

# 打印横幅
print_banner() {
    echo -e "${BLUE}"
    cat << 'EOF'
    ╔══════════════════════════════════════════════════════════════╗
    ║                  认证服务强制清理工具                         ║
    ║                Auth Service Force Cleanup                   ║
    ║                                                              ║
    ║  警告: 此脚本将强制终止所有认证服务进程！                     ║
    ╚══════════════════════════════════════════════════════════════╝
EOF
    echo -e "${NC}"
}

# 查找所有认证服务进程
find_auth_processes() {
    log_info "查找认证服务进程..."
    
    # 使用多种方法查找进程
    local pids=""
    
    # 方法1: 通过进程名查找
    local name_pids=$(ps aux | grep -E "auth_service" | grep -v grep | grep -v "cleanup_auth_service" | awk '{print $2}' || true)
    
    # 方法2: 通过端口查找
    local port_pids=""
    if command -v lsof >/dev/null 2>&1; then
        port_pids=$(lsof -ti :8008 2>/dev/null || true)
    fi
    
    # 合并PID列表
    pids="$name_pids $port_pids"
    
    # 去重
    pids=$(echo $pids | tr ' ' '\n' | sort -u | tr '\n' ' ')
    
    echo "$pids"
}

# 强制终止进程
force_kill_process() {
    local pid=$1
    
    if [[ ! "$pid" =~ ^[0-9]+$ ]]; then
        return
    fi
    
    # 检查进程是否存在
    if ! kill -0 $pid 2>/dev/null; then
        log_info "进程 $pid 已不存在"
        return
    fi
    
    # 获取进程信息
    local process_info=$(ps -p $pid -o pid,ppid,cmd --no-headers 2>/dev/null || echo "进程信息不可用")
    log_warn "强制终止进程 PID: $pid"
    log_info "进程信息: $process_info"
    
    # 直接使用SIGKILL
    if kill -KILL $pid 2>/dev/null; then
        log_info "进程 $pid 已被强制终止"
    else
        log_error "无法终止进程 $pid (可能需要sudo权限)"
    fi
}

# 清理PID文件
cleanup_pid_files() {
    log_info "清理PID文件..."

    local pid_files=(
        "/tmp/auth_service.pid"
        "/var/run/auth_service.pid"
        "/tmp/auth_service_*.pid"
    )

    for pid_file in "${pid_files[@]}"; do
        if [[ -f "$pid_file" ]]; then
            # 检查PID文件中的进程是否真的在运行
            if [[ -r "$pid_file" ]]; then
                local old_pid=$(cat "$pid_file" 2>/dev/null || echo "")
                if [[ -n "$old_pid" && "$old_pid" =~ ^[0-9]+$ ]]; then
                    if kill -0 "$old_pid" 2>/dev/null; then
                        log_warn "PID文件 $pid_file 中的进程 $old_pid 仍在运行"
                    else
                        log_info "PID文件 $pid_file 中的进程 $old_pid 已不存在，清理文件"
                    fi
                fi
            fi

            log_info "删除PID文件: $pid_file"
            rm -f "$pid_file"
        fi
    done
}

# 清理端口占用
cleanup_port_bindings() {
    log_info "检查端口8008占用情况..."

    # 使用lsof检查并强制清理
    if command -v lsof >/dev/null 2>&1; then
        local port_usage=$(lsof -i :8008 2>/dev/null || true)
        if [[ -n "$port_usage" ]]; then
            log_warn "端口8008仍被占用:"
            echo "$port_usage"

            # 尝试终止占用端口的进程
            local port_pids=$(lsof -ti :8008 2>/dev/null || true)
            for pid in $port_pids; do
                log_warn "终止占用端口8008的进程: $pid"
                kill -TERM "$pid" 2>/dev/null || true
                sleep 1
                if kill -0 "$pid" 2>/dev/null; then
                    log_warn "强制终止进程: $pid"
                    kill -KILL "$pid" 2>/dev/null || true
                fi
            done

            # 等待端口释放
            log_info "等待端口释放..."
            for i in {1..10}; do
                sleep 1
                local remaining_usage=$(lsof -i :8008 2>/dev/null || true)
                if [[ -z "$remaining_usage" ]]; then
                    log_info "端口8008已释放"
                    break
                fi
                log_warn "端口8008仍被占用，等待中... ($i/10)"
            done
        fi
    fi

    # 使用netstat检查
    local netstat_result=$(netstat -tlnp 2>/dev/null | grep ":8008 " || true)
    if [[ -n "$netstat_result" ]]; then
        log_warn "netstat显示端口8008仍被占用:"
        echo "$netstat_result"
    else
        log_info "端口8008已释放"
    fi
}

# 主清理函数
main_cleanup() {
    print_banner
    
    log_warn "开始强制清理认证服务..."
    
    # 查找所有相关进程
    local pids=$(find_auth_processes)
    
    if [[ -z "$pids" ]]; then
        log_info "未找到认证服务进程"
    else
        log_warn "发现认证服务进程: $pids"
        log_warn "将强制终止所有进程..."
        
        # 强制终止所有进程
        for pid in $pids; do
            force_kill_process $pid
        done
        
        # 等待进程完全退出
        log_info "等待进程完全退出..."
        sleep 2
    fi
    
    # 清理PID文件
    cleanup_pid_files
    
    # 再次检查进程
    log_info "再次检查残留进程..."
    local remaining_pids=$(find_auth_processes)
    
    if [[ -n "$remaining_pids" ]]; then
        log_error "仍有残留进程: $remaining_pids"
        log_warn "尝试第二轮强制清理..."
        
        for pid in $remaining_pids; do
            force_kill_process $pid
        done
        
        sleep 2
    fi
    
    # 检查端口状态
    cleanup_port_bindings
    
    # 最终检查
    local final_pids=$(find_auth_processes)
    if [[ -z "$final_pids" ]]; then
        log_info "=== 清理完成：所有认证服务进程已终止 ==="
    else
        log_error "=== 清理失败：仍有进程残留: $final_pids ==="
        log_error "可能需要sudo权限或重启系统"
    fi
}

# 显示帮助
show_help() {
    echo "认证服务强制清理工具"
    echo ""
    echo "用法: $0 [选项]"
    echo ""
    echo "选项:"
    echo "  -f, --force    强制清理（默认）"
    echo "  -h, --help     显示帮助信息"
    echo ""
    echo "警告:"
    echo "  此脚本将强制终止所有认证服务进程！"
    echo "  请确保没有重要的认证服务实例正在运行。"
    echo ""
    echo "示例:"
    echo "  $0              # 执行强制清理"
    echo "  $0 --force      # 执行强制清理"
    echo ""
}

# 解析命令行参数
case "${1:-}" in
    -h|--help)
        show_help
        exit 0
        ;;
    -f|--force|"")
        main_cleanup
        ;;
    *)
        log_error "未知参数: $1"
        show_help
        exit 1
        ;;
esac
